package com.kk.service.impl;

import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.common.response.ApiResponse;
import cloud.tianai.captcha.spring.application.ImageCaptchaApplication;
import cloud.tianai.captcha.spring.vo.CaptchaResponse;
import cloud.tianai.captcha.spring.vo.ImageCaptchaVO;
import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kk.pojo.dto.CaptchaVerifyDTO;
import com.kk.pojo.vo.CaptchaVO;
import com.kk.service.CaptchaService;
import com.kk.utils.RedisUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import com.kk.constrants.RedisConstants;
/**
 * 验证码服务实现类
 *
 * @author kl
 * @version 1.0
 * @date 2025/10/17 上午11:26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CaptchaServiceImpl implements CaptchaService {

    private final ImageCaptchaApplication imageCaptchaApplication;
    private final RedisUtils redisUtils;
    private final ObjectMapper objectMapper;



    /**
     * 生成滑动验证码
     *
     * @return 验证码VO
     */
    @Override
    public CaptchaVO generateCaptcha() {
        try {
            // 生成滑块验证码
            CaptchaResponse<ImageCaptchaVO> response = imageCaptchaApplication
                    .generateCaptcha(CaptchaTypeConstant.SLIDER);

            // CaptchaResponse 没有 isSuccess 方法，直接使用返回的数据
            if (response == null || response.getId() == null) {
                log.error("生成验证码失败: response 为空或 ID 为空");
                return null;
            }

            // 获取验证码ID
            String captchaId = response.getId();

            // 获取验证码数据（ImageCaptchaVO）
            ImageCaptchaVO captchaData = response.getCaptcha();
            if (captchaData == null) {
                log.error("生成验证码失败: captchaData 为空");
                return null;
            }

            // ImageCaptchaVO 继承自 Map，可以直接使用
            // 构建返回VO
            CaptchaVO captchaVO = new CaptchaVO();
            captchaVO.setCaptchaId(captchaId);
            captchaVO.setBackgroundImage(String.valueOf(captchaData.getBackgroundImage()));
            captchaVO.setTemplateImage(String.valueOf(captchaData.getTemplateImage()));
            captchaVO.setType(CaptchaTypeConstant.SLIDER);

            // 将验证码信息存入Redis，设置过期时间
            String redisKey = RedisConstants.CAPTCHA_KEY_PREFIX + captchaId;
            redisUtils.set(redisKey, captchaId, RedisConstants.CAPTCHA_EXPIRE_TIME, TimeUnit.MINUTES);

            log.info("生成验证码成功, captchaId: {}", captchaId);
            return captchaVO;

        } catch (Exception e) {
            log.error("生成验证码异常", e);
            return null;
        }
    }

    /**
     * 验证滑动验证码
     *
     * @param verifyDTO 验证请求DTO
     * @return 验证结果
     */
    @Override
    public boolean verifyCaptcha(CaptchaVerifyDTO verifyDTO) {
        String captchaId = null;
        try {
            captchaId = verifyDTO.getCaptchaId();
            String redisKey = RedisConstants.CAPTCHA_KEY_PREFIX + captchaId;

            // 检查验证码是否存在
            Boolean hasKey = redisUtils.hasKey(redisKey);
            if (Boolean.FALSE.equals(hasKey)) {
                log.warn("验证码不存在或已过期, captchaId: {}", captchaId);
                return false;
            }

            // 解析滑动轨迹
            ImageCaptchaTrack track = objectMapper.readValue(
                    verifyDTO.getTrackData(),
                    ImageCaptchaTrack.class
            );

            // 验证滑块 - 注意：这里使用的是 ApiResponse，它才有 isSuccess() 方法
            ApiResponse<?> response = imageCaptchaApplication.matching(captchaId, track);

            // 删除已使用的验证码（无论验证成功还是失败，都删除以防止重复使用）
            redisUtils.delete(redisKey);

            // ApiResponse 有 isSuccess() 和 getMsg() 方法
            if (response.isSuccess()) {
                log.info("验证码验证成功, captchaId: {}", captchaId);
                return true;
            } else {
                log.warn("验证码验证失败, captchaId: {}, msg: {}", captchaId, response.getMsg());
                return false;
            }

        } catch (Exception e) {
            log.error("验证验证码异常, captchaId: {}", captchaId, e);
            return false;
        }
    }
}